package com.community.util;

import java.util.*;

public class TreeUtil {

    public static List<Map> geneTree(Collection<Map> list){
        List<Map> ret = new ArrayList<>();
        Iterator<Map> it = list.iterator();
        while (it.hasNext()){
            Map record = it.next();
            Object pid = record.get("pid");
            if(!existsInList(pid,list)){
                record.put("nodes",getChildren(record,list));
                ret.add(record);
            }
        }
        return ret;
    }

    private static boolean existsInList(Object pid,Collection<Map> list){
        boolean ret = false;
        if(pid ==null){
            return ret;
        }
        for(Map map:list){
            if(map.get("id")!=null && map.get("id").equals(pid)){
                ret = true;
                break;
            }
        }
        return ret;
    }

    private static Map getParent(Map son,Collection<Map> list){
        Object pid = son.get("pid");
        if(pid == null){
            return null;
        }else{
            for(Map map:list){
                if(map.get("id")!=null && map.get("id").equals(pid)){
                    return map;
                }
            }
        }
        return null;
    }

    private static Set<Map> getAllParents(Map son,Collection<Map> list){
        Set<Map> parents = new HashSet<>();
        Map parent = getParent(son,list);
        while (parent!=null){
            parents.add(parent);
            parent = getParent(parent,list);
        }
        return parents;
    }

    public static void addParents(List<Map> tarList, List<Map> allList) {
        Set<Map> parents = new HashSet<>();
        tarList.forEach(map ->
                {getAllParents(map,allList).forEach(parent ->
                    {if(!existsInList(parent.get("id"),tarList)){parents.add(parent);}});
                });
        tarList.addAll(parents);
    }

    public static List<Map> geneSortedTree(List<Map> list,String parentId,String sortField){
        List<Map> ret = new ArrayList<>();
        Iterator<Map> it = list.iterator();
        while (it.hasNext()){
            Map record = it.next();
            if(parentId == null?record.get("pid")==null:parentId.equals(record.get("pid"))){
                record.put("nodes",getSortedChildren(record, list, sortField));
                ret.add(record);
            }
        }
        sortCollection(ret,sortField);
        return ret;
    }

    private static void sortCollection(List<Map> list, final String sortField){
        Collections.sort(list, new Comparator<Map>() {
            @Override
            public int compare(Map a, Map b) {
                Integer sortA = (Integer)a.get(sortField);
                Integer sortB = (Integer)b.get(sortField);
                if(sortA!=null && sortB!=null){
                    return sortA.compareTo(sortB);
                }
                return a.get("id").toString().compareTo(b.get("id").toString());
            }
        });
    }

    /**
     * 参数：指定一个分类和分类列表，
     * 过程：在列表中迭代 ，
     * 把列表中属于该分类的一级及一级以下子节点集合list设置成指定分类的childrens属性
     * 结果：获取孩子节点（孩子节点的孩子节点已经设置好了）
     * @return
     */
    private static List<Map> getChildren(Map record,Collection<Map> list){
        if(record.get("id") == null){
            return null;
        }
        String id = record.get("id")+"";
        List<Map> children = new ArrayList<>();
        for(Map m : list){
            String pid = m.get("pid")+"";
            if(id.equals(pid) ){
                m.put("pids",(record.get("pids")==null?"":(record.get("pids")+","))+record.get("id"));
                m.put("ptexts",(record.get("ptexts")==null?"":(record.get("ptexts")+">"))+record.get("text"));
                m.put("nodes",getChildren(m, list));
                children.add(m);
            }
        }
        if(children.size()>0){
            return children;
        }else{
            return null;
        }
    }

    private static List<Map> getSortedChildren(Map record,List<Map> list,String sortField){
        if(record.get("id") == null){
            return null;
        }
        String id = record.get("id")+"";
        List<Map> children = new ArrayList<>();
        for(Map m : list){
            String pid = m.get("pid")+"";
            if(id.equals(pid) ){
                m.put("ptexts",(record.get("ptexts")==null?"":(record.get("ptexts")+">"))+record.get("text"));
                m.put("nodes",getSortedChildren(m, list, sortField));
                children.add(m);
            }
        }
        if(children.size()>0){
            sortCollection(children,sortField);
            return children;
        }else{
            return null;
        }
    }
    /**
     * 用于将树节点的cnt字段由子节点向父节点汇总
     * @param list
     * @return
     */
    public static Long sumTree(List<Map> list){
        Long sum = 0L;
        Iterator<Map> it = list.iterator();
        while (it.hasNext()){
            Map record = it.next();
            Long cnt = (Long)record.get("cnt");
            if(cnt ==null){
                cnt = 0l;
                record.put("cnt",cnt);
            }
            List nodes = (List<Map>)record.get("nodes");
            if(nodes != null && nodes.size()>0){
                record.put("cnt",cnt+sumTree(nodes));
            }
            sum += (Long)record.get("cnt");
        }
        return sum;
    }

    public static void main(String[] args) {
        List<Map> list=new ArrayList<>();

        Map map2_1=new HashMap<>();
        map2_1.put("name","2级节点-1");
        map2_1.put("cnt",1L);
        Map map2_2=new HashMap<>();
        map2_2.put("name","2级节点-2");
        map2_2.put("cnt",1L);

        List<Map> list2=new ArrayList<>();
        list2.add(map2_1);
        list2.add(map2_2);

        Map map1_1=new HashMap<>();
        map1_1.put("name", "1级节点-1");
        Map map1_2=new HashMap<>();
        map1_2.put("name", "1级节点-2");

        map1_1.put("nodes",list2);

        list.add(map1_1);
        list.add(map1_2);

        sumTree(list);

        System.out.println(list);

    }


}
